import pandas as pd
from django.db.models import Q
from sklearn.metrics.pairwise import cosine_similarity

from Shop.models import Commodity
from User.models import MyUser as User
from .models import OrderShip, Order


def getdata():
    # 获取所有用户的购买记录
    all_user = User.objects.all()
    all_user_id = []
    all_commodity_id = []
    all_commodity_quantity = []
    for user in all_user:
        user_orders = Order.objects.filter(~Q(status_buyer='未付款'), user=user)
        user_commodity = {}
        for user_order in user_orders:
            order_ships = OrderShip.objects.filter(order=user_order)
            for order_ship in order_ships:
                commodity = order_ship.commodity
                user_commodity[commodity.id] = order_ship.quantity
        for commodity_id in user_commodity.keys():
            all_user_id.append(user.id)
            all_commodity_id.append(commodity_id)
            all_commodity_quantity.append(user_commodity[commodity_id])
    data = {'user_id': all_user_id, 'commodity_id': all_commodity_id, 'commodity_quantity': all_commodity_quantity}
    return data


def processdata(data):
    # 处理数据
    df = pd.DataFrame(data)
    # 生成用户-物品矩阵
    user_item_matrix = df.pivot_table(index='user_id', columns='commodity_id', values='commodity_quantity').fillna(0)
    # 计算物品相似度 cosine_similarity表示余弦相似度
    item_similarity = cosine_similarity(user_item_matrix.T)
    # 生成物品相似度矩阵
    item_similarity_df = pd.DataFrame(item_similarity, index=user_item_matrix.columns, columns=user_item_matrix.columns)

    return user_item_matrix, item_similarity_df

def recommend_items(user_id, user_item_matrix, item_similarity_df, k):
    # 用户历史购买物品
    user_items = user_item_matrix.loc[user_id]
    # 计算用户未购买物品的得分
    scores = item_similarity_df[user_items.index].dot(user_items).div(item_similarity_df[user_items.index].sum())
    # 排除已购买物品
    #scores = scores.drop(user_items[user_items > 0].index)
    # 返回得分最高的k个物品
    return scores.nlargest(k)


def recommend(user_id, num=3):
    data = getdata()
    user_item_matrix, item_similarity_df = processdata(data)
    scores = recommend_items(user_id, user_item_matrix, item_similarity_df, num)
    commodity = []
    for i in scores.index.tolist():
        commodity.append(Commodity.objects.get(id=i))
    return commodity
